


import itemHandle from "./itemHandle";
import playerHandle from "./playerHandle";
import bagHandle from "./bagHandle";
import { gameConfigHandle } from "core/config/gameConfig";
import utils from "core/utils/utils";
import { ItemModel, PetItemModel } from "core/model/itemModel";
import Random from "core/utils/random";
import { PlayerModel } from "core/model/playerModel";
import gameUtils from "core/utils/gameUtils";
import partnerHandle from "./partnerHandle";


class PetHandle {
    constructor() {

    }

    create(petID: number, floor: number, rand: Random,
        { lvl, lucky, quality, minQuality, maxQuality, elements, star }: { lvl?: number, lucky?: number, quality?: number, minQuality?: number, maxQuality?: number, elements?: number[], star?: number }) {
        if (utils.isNull(quality)) {
            quality = 0
        }
        if (petID === null) {
            petID = utils.getOneFromArray(gameConfigHandle.gameConfig.pet.callPetList, rand)
        }
        let petItemConfig = gameConfigHandle.configByID[petID]

        if (utils.isNull(elements) || elements.length === 0) {
            let elementIDs = [0, 1, 2, 3]
            let elementAmount = this.getElementRate(floor, rand)
            if (elementAmount > 3) {
                elementAmount = 3
            }
            elements = utils.getRandomArrayNoRepeat(elementIDs, elementAmount, rand)
        }

        //测试
        // elements = [0, 1, 2, 3]

        // let attriQualitys1 = new Array(petItemConfig.attris.length).fill(0)
        // if (utils.isNull(star)) {
        //     star = Math.floor(2 + (floor / 4))
        //     if (star > 15) {
        //         star = 15
        //     }
        //     star = utils.getRandomNumber(Math.ceil(star * 0.6), star, rand)
        // }
        // for (let i = 0; i < star; i++) {
        //     let j = utils.getRandomNumber(0, petItemConfig.attris.length - 1, rand)
        //     attriQualitys1[j] += 1
        // }
        let petItem = new PetItemModel({
            tid: petID,
            quality: quality,
            elements: elements,
            // attriQualitys1: attriQualitys1,
        })
        if (!utils.isNull(lvl)) {
            petItem.lvl = lvl
        }
        let item = itemHandle.create({
            stack: 1,
            tid: petID,
            new: true,
        })
        item.pet = petItem
        return item
    }



    getElementRate(lucky: number, rand: Random) {
        let equipmentQualityOdds = [
            [500, 50, 2, 0, 0],
            [0, 1, 0, 0.1, 0.1]
        ]

        let difficultyOdds = equipmentQualityOdds
        let odds = difficultyOdds[0].slice()
        let oddsCoe = difficultyOdds[1]
        let total = 0
        let len = 4
        let pers = []
        for (let i = 0; i < len; i++) {
            odds[i] += lucky * oddsCoe[i]
            total += odds[i]
        }
        for (let i = 0; i < len; i++) {
            pers[i] = odds[i] / total * 100
        }
        let r = rand.floor(total)
        let i = 0
        while (i < len) {
            if (r <= odds[i]) {
                break
            }
            r -= odds[i]
            i++
        }
        let qualityLvl = i
        if (qualityLvl > 4) {
            qualityLvl = 0
        }
        qualityLvl += 1
        return qualityLvl

    }

    getQualityLvl(minQualityLvl: number = 0, maxQuality: number = 5, lucky: number, rand: Random) {
        let { total, odds } = this.getQualityRate(minQualityLvl, maxQuality, lucky)
        let len = maxQuality
        let r = rand.intn(total)
        let i = minQualityLvl
        while (i <= len) {
            if (r <= odds[i]) {
                break
            }
            r -= odds[i]
            i++
        }
        let qualityLvl = i
        if (qualityLvl > maxQuality) {
            qualityLvl = maxQuality
        }
        return qualityLvl
    }

    getQualityRate(minQualityLvl: number = 0, maxQuality: number = 5, lucky: number) {
        let equipmentQualityOdds = [
            [100, 30, 15, 5, 0, 0],
            [0, 1, 2, 1, 0.5, 0]
        ]
        let difficultyOdds = equipmentQualityOdds
        let odds = difficultyOdds[0].slice()
        let oddsCoe = difficultyOdds[1]
        let total = 0
        let len = maxQuality
        let pers = []
        for (let i = minQualityLvl; i <= len; i++) {
            odds[i] += lucky * oddsCoe[i]
            total += odds[i]
        }
        for (let i = minQualityLvl; i <= len; i++) {
            pers[i] = odds[i] / total * 100
        }
        return { total, odds, pers }
    }

    getOdds(difficultyOdds, lucky: number, rand: Random) {
        let odds = difficultyOdds[0].slice()
        let oddsCoe = difficultyOdds[1]
        let total = 0
        let maxQuality = odds.length - 1
        let pers = []
        for (let i = 0; i <= maxQuality; i++) {
            odds[i] += lucky * oddsCoe[i]
            total += odds[i]
        }
        for (let i = 0; i <= maxQuality; i++) {
            pers[i] = odds[i] / total * 100
        }

        let r = rand.intn(total)
        let i = 0
        while (i <= maxQuality) {
            if (r <= odds[i]) {
                break
            }
            r -= odds[i]
            i++
        }
        let qualityLvl = i
        if (qualityLvl > maxQuality) {
            qualityLvl = maxQuality
        }
        return { total, odds, pers, qualityLvl }
    }

    destroy(player: PlayerModel, petItem: ItemModel) {
        let equipmentConfig = gameConfigHandle.gameConfig.pet
        let getItem = {}
        equipmentConfig.destroy.forEach(e => {
            let name = e.itemID
            let amounts = e.amount
            let amount = amounts[0]
            if (petItem.pet.quality > 0) {
                amount = amounts[1] * Math.pow(3, petItem.pet.quality)
            }
            getItem[name] = amount
        })

        let petConfig = gameConfigHandle.gameConfig.pet;
        let { totalStar2 } = this.getTotalStar(petItem)
        let needConfig = gameConfigHandle.gameConfig.need
        for (let i = 0; i < totalStar2; i++) {
            let res = gameUtils.getNeedResource(player, needConfig.petStarLvlup, i)
            utils.entries(res.needItems).forEach(item => {
                let itemType = item[0]
                let amount = item[1]
                if (!getItem[itemType]) {
                    getItem[itemType] = 0
                }
                getItem[itemType] += amount
            })
        }

        for (let i = 0; i < petItem.pet.quality; i++) {
            let res = gameUtils.getNeedResource(player, needConfig.petSyncNeed, i, Math.pow(3, petItem.pet.quality - i - 1))
            utils.entries(res.needItems).forEach(item => {
                let itemType = item[0]
                let amount = item[1]
                if (!getItem[itemType]) {
                    getItem[itemType] = 0
                }
                getItem[itemType] += amount
            })
        }
        utils.entries(getItem).forEach(item => {
            let itemType = Number(item[0])
            let amount: any = item[1]
            bagHandle.addItem(player.bag, itemType, amount)
        })


        return getItem
    }




    getTotalStar = (item: ItemModel) => {
        let totalStar1 = 0, totalStar2 = 0, totalStar = 0
        let petItemConfig = gameConfigHandle.configByID[item.tid]
        petItemConfig.attris.forEach((_, index) => {
            totalStar1 += (item.pet.attriQualitys1[index] || 0) //+ 1
            totalStar2 += (item.pet.attriQualitys2[index] || 0)
        })
        totalStar = totalStar1 + totalStar2
        return { totalStar1, totalStar2, totalStar }
    }

    getInheritNeedLvl = (player, selectPets, inheritLvl, inheritQuality, inheritStar1, inheritStar2, inheritElement) => {
        let mainPet = player.petBag.items[selectPets[0]]
        let subPet = player.petBag.items[selectPets[1]]
        let lvl = 1
        if (mainPet && subPet) {
            let pet = new ItemModel(mainPet)
            if (inheritLvl) {
                pet.pet.lvl = subPet.pet.lvl
            }
            if (inheritQuality) {
                lvl += subPet.pet.quality * lvl * 3
            }
            let { totalStar, totalStar1, totalStar2 } = petHandle.getTotalStar(subPet)
            if (inheritStar1) {
                lvl += totalStar1
            }
            if (inheritStar2) {
                lvl += totalStar2
            }
            if (inheritElement) {
                lvl += subPet.pet.elements.length * 3
            }

        }
        return lvl
    }

    getPetAttriValue = (item: ItemModel, index) => {
        let attriLvlupConfig = gameConfigHandle.gameConfig.attriLvlup
        let petConfig = gameConfigHandle.gameConfig.pet
        let petItemConfig = gameConfigHandle.configByID[item.tid]
        let attriName = petItemConfig.attris[index]
        let starLvl1 = 0//(item.pet.attriQualitys1[index] || 1) - 1
        let starLvl2 = (item.pet.attriQualitys2[index] || 0)
        let value = partnerHandle.getAttriValues(attriName, item.pet.lvl, attriLvlupConfig.petAttriValues)
        value = value * (1 + petConfig.attriCoeAdd * (starLvl1 + starLvl2) / 100) * (1 + item.pet.quality * petConfig.qualityCoeAdd / 100)

        //元素加成
        let elements = []
        item.pet.elements.forEach(i => {
            elements.push(gameConfigHandle.gameConfig.pet.elementAttri[i])
        })
        if (elements.includes(attriName)) {
            value *= 1 + utils.getIncValues(gameConfigHandle.gameConfig.pet.elementAttriAdd, item.pet.quality) / 100
        }

        value = utils.floor(value, attriLvlupConfig.attriValuesList[attriName][4] || 0)
        return value
    }

}

let petHandle = new PetHandle()
export default petHandle